package com.samphanie.security.security.filter;

import cn.hutool.core.util.StrUtil;
import com.samphanie.common.constants.SysConfigKeyConstants;
import com.samphanie.common.constants.SystemConstants;
import com.samphanie.common.enums.ResultCode;
import com.samphanie.common.service.IRedisService;
import com.samphanie.common.utils.ApiResponse;
import com.samphanie.common.utils.ResponseUtil;
import com.samphanie.security.config.JwtUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;

/**
 * @Description:
 * @Author ZSY
 * @createTime 2021/10/20 10:21
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class AuthGlobalFilter extends OncePerRequestFilter {

    private final IRedisService redisService;

    @Override
    protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain chain) throws ServletException, IOException {

        String token = request.getHeader(SystemConstants.JWT_TOKEN_HEADER);

        if (StrUtil.isBlank(token) || !StrUtil.startWithIgnoreCase(token, SystemConstants.JWT_TOKEN_PREFIX)) {
            chain.doFilter(request, response);
            return;
        }

        try {
            // 黑名单token(登出、修改密码)校验
            // JWT唯一标识
            String jti = JwtUtils.getJti();
            boolean isBlack = redisService.hasKey(SystemConstants.TOKEN_BLACKLIST_PREFIX + jti);
            if (isBlack) {
                ApiResponse<?> result = ApiResponse.failed(ResultCode.USER_ERROR_A0230);
                ResponseUtil.responseWriter(response, MediaType.APPLICATION_JSON_VALUE, HttpStatus.OK.value(), result);
                return;
            }

            // 冻结账户校验
            String client = JwtUtils.getClient();
            String username = JwtUtils.getUsername();
            boolean isStatus = redisService.hasKey(SysConfigKeyConstants.getUserBlackKey(client, username));
            if (isStatus) {
                ApiResponse<?> result = ApiResponse.failed(ResultCode.USER_ERROR_A0202);
                ResponseUtil.responseWriter(response, MediaType.APPLICATION_JSON_VALUE, HttpStatus.OK.value(), result);
                return;
            }
        } catch (Exception e) {
            ApiResponse<?> result = ApiResponse.failed(ResultCode.USER_ERROR_A0340);
            ResponseUtil.responseWriter(response, MediaType.APPLICATION_JSON_VALUE, HttpStatus.OK.value(), result);
            return;
        }

        chain.doFilter(request,response);
    }
}
